home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS01.ADF / C / Mandel.c < prev    next >
C/C++ Source or Header  |  1986-01-09  |  9KB  |  292 lines

  1. /*********************************************************************
  2. ******                                              ******************
  3. ****** Mandel.c - A Mandelbrot Set viewer for Amiga ******************
  4. ******                                              ******************
  5. ****** by Kevin A. Bjorke                           ******************
  6. ******    25724 Salceda Road                        ******************
  7. ******    Valencia, CA 91355                        ******************
  8. ******    CIS:74756,464                             ******************
  9. ******                                              ******************
  10. *********************************************************************/
  11.  
  12. #include <exec/types.h>
  13. #include <exec/tasks.h>
  14. #include <exec/libraries.h>
  15. #include <exec/devices.h>
  16. #include <devices/keymap.h>
  17. #include <graphics/copper.h>
  18. #include <graphics/display.h>
  19. #include <graphics/gfxbase.h>
  20. #include <graphics/text.h>
  21. #include <graphics/view.h>
  22. #include <graphics/gels.h>
  23. #include <graphics/regions.h>
  24. #include <hardware/blit.h>
  25. #include <intuition/intuition.h>
  26. #include <intuition/intuitionbase.h>
  27. #include <math.h>
  28.  
  29. #ifndef TRUE
  30. #define TRUE 1
  31. #define FALSE 0
  32. #endif
  33.  
  34. #define  XPIXSIDE 150                  /* Width of Mandel box in pixels */
  35. #define  YPIXSIDE 150                  /* Height ''     ''      ''      */
  36. #define  LIMIT 127                     /* max iterations per pixel */
  37. #define  XSTART 5                      /* start of box in X */
  38. #define  YSTART 12                     /*  ''    ''    '' Y */
  39. #define  XTOP XSTART+XPIXSIDE
  40. #define  YTOP YSTART+YPIXSIDE
  41. #define  OKAY ((xmp>=XSTART)&&(xmp<XTOP)&&(ymp>=YSTART)&&(ymp<YTOP))
  42.  
  43. struct   GfxBase       *GfxBase;       /* Export the library pointers */
  44. struct   IntuitionBase *IntuitionBase;
  45. struct   RastPort      *rp;            /* Graphics structures           */
  46. struct   ViewPort      *vp;
  47.  
  48. struct TextAttr TestFont = {
  49.        "topaz.font",                   /* Standard system font */
  50.        8,    0,    0
  51. };
  52.  
  53. struct   Window        *w;             /* Intuition structures        */ 
  54. struct   Screen        *screen;
  55. struct   IntuiMessage  *message;
  56.  
  57. struct   NewScreen ns = {
  58.    0, 0,                               /* start position                */
  59.    320, 200, 4,                        /* width, height, depth          */
  60.    0, 1,                               /* detail pen, block pen         */
  61.    0,                                  /* Normal ViewMode               */
  62.    CUSTOMSCREEN,                       /* screen type                   */
  63.    &TestFont,                          /* font to use                   */
  64.    " Mandel ",                         /* default title for screen      */
  65.    NULL                                /* pointer to additional gadgets */
  66. };
  67.  
  68. struct NewWindow nw = {
  69.         0, 11,                         /* start position                */
  70.         320, 186,                      /* width, height                 */
  71.         -1, -1,                        /* detail pen, block pen         */
  72.         MOUSEBUTTONS|CLOSEWINDOW,      /* IDCMP flags                   */
  73.         ACTIVATE|WINDOWCLOSE,          /* window flags                  */
  74.         NULL,                          /* pointer to first user gadget  */
  75.         NULL,                          /* pointer to user checkmark     */
  76.         " Mouse Zooms In ",            /*  window title                 */
  77.         NULL,                          /* pointer to screen (set below) */
  78.         NULL,                          /* pointer to superbitmap        */
  79.         0, 0, 320, 186,                /* ignored since not sizeable    */
  80.         CUSTOMSCREEN                   /* type of screen desired        */
  81. };
  82.  
  83. double acorn = -2.0;                      /* real portion - corner */
  84. double bcorn = -1.25;                     /* complex portion - corner */
  85. double xside = 2.5;                       /* span of box side in complex space */
  86. double yside = 2.5;                       /* span of box side in complex space */
  87. double szlim = 2.;                        /* iterative size limit */
  88. double ac, bc;                            /* these set by code */
  89. double xgap, ygap;                        /* Likewise */
  90. int xm = XSTART, ym = YSTART;             /* pixel counters */
  91. int filled = FALSE;
  92.  
  93. /*****************
  94. ** Main Program **
  95. *****************/
  96.  
  97. main()
  98. {
  99.    ULONG  class;
  100.    USHORT code;
  101.    int xmp, ymp;
  102.  
  103.    xgap = xside/XPIXSIDE;
  104.    ygap = yside/YPIXSIDE;
  105.    ac = acorn;
  106.    bc = bcorn;
  107.    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
  108.    if (GfxBase == NULL)
  109.       exit();
  110.    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  111.    if (IntuitionBase == NULL) {
  112.       CloseLibrary(GfxBase);
  113.       exit();
  114.    }
  115.    screen = (struct Screen *)OpenScreen(&ns); 
  116.    if (screen == NULL) {
  117.       CloseLibrary(IntuitionBase);      CloseLibrary(GfxBase);
  118.       exit();
  119.    }
  120.    nw.Screen = screen;                /* Open window in our new screen */
  121.    w = (struct Window *)OpenWindow(&nw);
  122.    if (w == NULL) {
  123.       CloseScreen(screen);
  124.       CloseLibrary(IntuitionBase);
  125.       CloseLibrary(GfxBase);
  126.       exit();
  127.    }
  128.    vp = &screen->ViewPort;             /* Set colors in screen's VP    */
  129.    rp = w->RPort;                      /* Render into the window's RP  */
  130.  
  131.    /*  Set the color registers */
  132.    SetRGB4(vp, 0, 00, 00, 00);
  133.    SetRGB4(vp, 1, 15, 00, 00);    
  134.    SetRGB4(vp, 2, 00, 15, 00);   
  135.    SetRGB4(vp, 3, 00, 00, 15);
  136.    SetRGB4(vp, 4, 15, 15, 00);
  137.    SetRGB4(vp, 5, 15, 00, 15);
  138.    SetRGB4(vp, 6, 00, 15, 15);
  139.    SetRGB4(vp, 7, 08, 08, 08);
  140.    SetRGB4(vp, 8, 15, 08, 00);
  141.    SetRGB4(vp, 9, 00, 08, 15);
  142.    SetRGB4(vp,10, 08, 15, 08);
  143.    SetRGB4(vp,11, 14, 04, 02);
  144.    SetRGB4(vp,12, 04, 11, 01);
  145.    SetRGB4(vp,13, 13, 06, 15);
  146.    SetRGB4(vp,14, 02, 04, 06);
  147.    SetRGB4(vp,15, 15, 15, 15);
  148.    SetBPen(rp, 0);                    /* Insure clean text              */
  149.    fieldbox();
  150.    FOREVER {
  151.       while((message = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL) {
  152.          class = message->Class;
  153.          code  = message->Code;
  154.          xmp = w->MouseX;
  155.          ymp = w->MouseY;
  156.          ReplyMsg(message);       /* Can't reply until done using it!   */
  157.          if(class == CLOSEWINDOW) {                 /* Exit the program */
  158.             CloseWindow(w);
  159.             CloseScreen(screen);
  160.             CloseLibrary(IntuitionBase);
  161.             CloseLibrary(GfxBase);
  162.             exit();
  163.          };
  164.          if(class == MOUSEBUTTONS && code == SELECTDOWN) { /* start over */
  165.             if (OKAY) {
  166.                span_box(xmp,ymp);
  167.             }
  168.          }
  169.       }
  170.       if (!filled)
  171.           filled = Mandel();
  172.    }
  173.    CloseWindow(w);
  174.    CloseScreen(screen);
  175.    CloseLibrary(IntuitionBase);
  176.    CloseLibrary(GfxBase);
  177. }
  178.  
  179. Mandel()
  180. {
  181.    SHORT c;
  182.  
  183.    c = Mandcolor(ac,bc);
  184.    SetAPen(rp,c);
  185.    WritePixel(rp,xm,ym);
  186.    if (++xm >= XTOP) {
  187.       xm = XSTART;
  188.       bc = bcorn;
  189.       ac += ygap;
  190.       if (++ym >= YTOP) return(TRUE);
  191.    } else {
  192.       bc += xgap;
  193.    }
  194.    return(FALSE);
  195. }
  196.  
  197. /***************************
  198. ** Mandelbrot calculation **
  199. ***************************/
  200. int Mandcolor(rl,im)
  201.    double rl, im;       /* real and imaginary parts of number */
  202. {
  203.    int ct;
  204.    double az = 0., bz = 0.;
  205.    double tm;
  206.    double sqrt();
  207.  
  208.    for (ct = 0;ct < LIMIT; ++ct) {
  209.       tm = az*az - bz*bz + rl;
  210.       bz = 2*az*bz + im;
  211.       az = tm;
  212.       if (sqrt(az*az+bz*bz) > szlim) break;
  213.    }
  214.    ct = (ct >> 3) & 15;
  215.    return(ct);
  216. }
  217.  
  218. fieldbox()
  219. {
  220.    SetAPen(rp, 15);                   /* Clear the drawing area */
  221.    SetDrMd(rp, JAM1);
  222.    RectFill(rp, (XSTART-1), (YSTART-1), XTOP, YTOP);
  223. }
  224.  
  225. span_box(xi,yi)
  226.    int xi, yi;
  227. {
  228.    ULONG  class;
  229.    USHORT code;
  230.    int x1, y1, x2, y2, xt, yt, xs, ys, xmp, ymp;
  231.  
  232.    xt = xi;
  233.    yt = yi;
  234.    ac = acorn += (yi-YSTART)*ygap;
  235.    bc = bcorn += (xi-XSTART)*xgap;
  236.    xm = XSTART;
  237.    ym = YSTART;
  238.    filled = FALSE;
  239.    SetAPen(rp, 8);
  240.    SetDrMd(rp, JAM1|COMPLEMENT);
  241.    FOREVER {
  242.       if (xt > xi) {
  243.          x1 = xi;
  244.          x2 = xt;
  245.       } else {
  246.          x1 = xt;
  247.          x2 = xi;
  248.       }
  249.       if (yt > yi) {
  250.          y1 = yi;
  251.          y2 = yt;
  252.       } else {
  253.          y1 = yt;
  254.          y2 = yi;
  255.       }
  256.       RectFill(rp, x1, y1, x2, y2);
  257.       RectFill(rp, x1, y1, x2, y2);
  258.       xmp = w->MouseX;
  259.       ymp = w->MouseY;
  260.       if (OKAY) {
  261.          xt = xmp;
  262.          yt = ymp;
  263.       }
  264.       while((message = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL) {
  265.          class = message->Class;
  266.          code  = message->Code;
  267.          ReplyMsg(message);       /* Can't reply until done using it!   */
  268.          if(class == CLOSEWINDOW) {                 /* Exit the program */
  269.             CloseWindow(w);
  270.             CloseScreen(screen);
  271.             CloseLibrary(IntuitionBase);
  272.             CloseLibrary(GfxBase);
  273.             exit();
  274.          };
  275.          if (OKAY) {
  276.             if(class == MOUSEBUTTONS && code == SELECTDOWN) {
  277.                xs = xt-xi;
  278.                ys = yt-yi;
  279.                xside = ((xs==0)?.5:xs)*xgap;
  280.                yside = ((ys==0)?.5:xs)*ygap;
  281.                xgap = xside/XPIXSIDE;
  282.                ygap = yside/YPIXSIDE;
  283.                fieldbox();
  284.                return(0);
  285.             }
  286.          }
  287.       }
  288.    }
  289. }
  290.  
  291. /***************** eof *****************************/
  292.